Week 13: Embedded Networking and Communications
Networking and Communication
Networking and communication enable electronic devices to interact and exchange information, such as sending messages. This can be done using wired or wireless connections and can involve various types of data, including sounds, images, and computer data.
Link to our group assignmentIdea
My idea is to create a network using a custom board with the ESP WROOM-02 D module. For this assignment, I will implement Client-Server Wi-Fi Communication using the HTTP protocol .
A client-server Wi-Fi communication setup allows communication between a client device (like my ESP32) and a server device (such as a web server or database server) over a Wi-Fi network. In this setup, the client device initiates communication by requesting data from the server device, which then responds by sending the requested information back to the client.
HTTP Protocol
The Hypertext Transfer Protocol (HTTP) is a client-server protocol used for transmitting data over the internet.
- HTTP messages consist of a request message from the client to the server , and a response message from the server to the client.
- The request message includes a method (such as GET or POST) that specifies the action to be performed, as well as a URL that identifies the resource to be accessed.
- The response message includes a status code that indicates the success or failure of the request, along with any data or resources returned by the server.
Designing the board
This week I’m using an ESP-WROOM-02 to build my custom board
- This is the PIN mapping of ESP-WROOM-02
The Circuit Design
Schematic Design
- PCB Design
- Top cut and trace design for milling the board
PCB with Soldered Components:
Connecting the board i made to the WIFI
So for the first step i am creating a web server in with my esp8266 board
-
In Arduino IDE open
File>Examples>Esp8266WebServer>HelloServer
- use this code to connect to wifi
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#ifndef STASSID
#define STASSID "Vinci"
#define STAPSK "Vinci2017!"
#endif
const char* ssid = STASSID;
const char* password = STAPSK;
ESP8266WebServer server(80);
const int led = 13;
void handleRoot() {
digitalWrite(led, 1);
server.send(200, "text/plain", "hello from esp8266!\r\n");
digitalWrite(led, 0);
}
void handleNotFound() {
digitalWrite(led, 1);
String message = "File Not Found\n\n";
message += "URI: ";
message += server.uri();
message += "\nMethod: ";
message += (server.method() == HTTP_GET) ? "GET" : "POST";
message += "\nArguments: ";
message += server.args();
message += "\n";
for (uint8_t i = 0; i < server.args(); i++) { message += " " + server.argName(i) + ": " + server.arg(i) + "\n"; }
server.send(404, "text/plain", message);
digitalWrite(led, 0);
}
void setup(void) {
pinMode(led, OUTPUT);
digitalWrite(led, 0);
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.println("");
// Wait for connection
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
if (MDNS.begin("esp8266")) { Serial.println("MDNS responder started"); }
server.on("/", handleRoot);
server.on("/inline", []() {
server.send(200, "text/plain", "this works as well");
});
server.on("/gif", []() {
static const uint8_t gif[] PROGMEM = {
0x47, 0x49, 0x46, 0x38, 0x37, 0x61, 0x10, 0x00, 0x10, 0x00, 0x80, 0x01,
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x2c, 0x00, 0x00, 0x00, 0x00,
0x10, 0x00, 0x10, 0x00, 0x00, 0x02, 0x19, 0x8c, 0x8f, 0xa9, 0xcb, 0x9d,
0x00, 0x5f, 0x74, 0xb4, 0x56, 0xb0, 0xb0, 0xd2, 0xf2, 0x35, 0x1e, 0x4c,
0x0c, 0x24, 0x5a, 0xe6, 0x89, 0xa6, 0x4d, 0x01, 0x00, 0x3b
};
char gif_colored[sizeof(gif)];
memcpy_P(gif_colored, gif, sizeof(gif));
// Set the background to a random set of colors
gif_colored[16] = millis() % 256;
gif_colored[17] = millis() % 256;
gif_colored[18] = millis() % 256;
server.send(200, "image/gif", gif_colored, sizeof(gif_colored));
});
server.onNotFound(handleNotFound);
/////////////////////////////////////////////////////////
// Hook examples
server.addHook([](const String& method, const String& url, WiFiClient* client, ESP8266WebServer::ContentTypeFunction contentType) {
(void)method; // GET, PUT, ...
(void)url; // example: /root/myfile.html
(void)client; // the webserver tcp client connection
(void)contentType; // contentType(".html") => "text/html"
Serial.printf("A useless web hook has passed\n");
Serial.printf("(this hook is in 0x%08x area (401x=IRAM 402x=FLASH))\n", esp_get_program_counter());
return ESP8266WebServer::CLIENT_REQUEST_CAN_CONTINUE;
});
server.addHook([](const String&, const String& url, WiFiClient*, ESP8266WebServer::ContentTypeFunction) {
if (url.startsWith("/fail")) {
Serial.printf("An always failing web hook has been triggered\n");
return ESP8266WebServer::CLIENT_MUST_STOP;
}
return ESP8266WebServer::CLIENT_REQUEST_CAN_CONTINUE;
});
server.addHook([](const String&, const String& url, WiFiClient* client, ESP8266WebServer::ContentTypeFunction) {
if (url.startsWith("/dump")) {
Serial.printf("The dumper web hook is on the run\n");
// Here the request is not interpreted, so we cannot for sure
// swallow the exact amount matching the full request+content,
// hence the tcp connection cannot be handled anymore by the
// webserver.
#ifdef STREAMSEND_API
// we are lucky
client->sendAll(Serial, 500);
#else
auto last = millis();
while ((millis() - last) < 500) {
char buf[32];
size_t len = client->read((uint8_t*)buf, sizeof(buf));
if (len > 0) {
Serial.printf("(<%d> chars)", (int)len);
Serial.write(buf, len);
last = millis();
}
}
#endif
// Two choices: return MUST STOP and webserver will close it
// (we already have the example with '/fail' hook)
// or IS GIVEN and webserver will forget it
// trying with IS GIVEN and storing it on a dumb WiFiClient.
// check the client connection: it should not immediately be closed
// (make another '/dump' one to close the first)
Serial.printf("\nTelling server to forget this connection\n");
static WiFiClient forgetme = *client; // stop previous one if present and transfer client refcounter
return ESP8266WebServer::CLIENT_IS_GIVEN;
}
return ESP8266WebServer::CLIENT_REQUEST_CAN_CONTINUE;
});
// Hook examples
/////////////////////////////////////////////////////////
server.begin();
Serial.println("HTTP server started");
}
void loop(void) {
server.handleClient();
MDNS.update();
}
- I got the IP Address from the serial Monitor.
I had opened my web server using the IP Address and the message that I had added in my code got displayed in my web UI.
Connecting the ESP8266 to webserver and displaying photodiode’s value using web UI
To extend the previous code to include converting the analog value from the photodiode to a percentage and displaying it on a web interface hosted by the ESP8266, you can follow this approach. We'll use the ESP8266WebServer library to create a simple web server that shows the percentage value:
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
const char* ssid = "Vinci";
const char* password = "Vinci2017!";
const int analogPin = A0;
const int maxAnalogValue = 1023; // Maximum value from ADC (10-bit resolution)
const int referenceVoltage = 3.3; // Reference voltage for ADC
ESP8266WebServer server(80);
void setup() {
Serial.begin(115200);
delay(100);
// Connect to Wi-Fi
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
// Print the IP address
Serial.println(WiFi.localIP());
// Setup web server routes
server.on("/", handleRoot);
// Start web server
server.begin();
Serial.println("HTTP server started");
}
void loop() {
// Handle client requests
server.handleClient();
// Read analog value from photodiode
int sensorValue = analogRead(analogPin);
// Convert analog value to percentage
float percentage = (sensorValue / float(maxAnalogValue)) * 100.0;
// Print the sensor value and percentage to serial monitor
Serial.print("Sensor value: ");
Serial.print(sensorValue);
Serial.print(", Percentage: ");
Serial.println(percentage);
// Wait for a second
delay(1000);
}
void handleRoot() {
// Create HTML page with the percentage value
String html = "<html><body>";
html += "<h1>Photodiode Reading</h1>";
html += "<p>Percentage: ";
html += getPercentage();
html += "%</p>";
html += "</body></html>";
// Send HTML response to client
server.send(200, "text/html", html);
}
String getPercentage() {
// Read analog value from photodiode
int sensorValue = analogRead(analogPin);
// Convert analog value to percentage
float percentage = (sensorValue / float(maxAnalogValue)) * 100.0;
// Format percentage as string
return String(percentage, 2); // Round to 2 decimal places
}
- After opening the serial monitor, i got this message
- Copied this IP and opened it in a browser
Networking
Connecting the Esp32 and the Esp wroom-02d
Their are two methods through which we can send data between 2 esp modules or through which the esp8266 WiFi modules can talk with each other. In both cases one esp8266 module is in client mode and the other one in server mode.
-
Send a HTTP request from client to server and the server
upon receiving the particular request will perform the desired action,
manipulate its Inputs Outputs etc. Consider this method as you are
sending an HTTP request
- Send a HTTP request from client to server. Up on receiving the request the server replies client with some useful information.
PROGRAMMING
Code for creating the server
//code for creating hot spot server
#include <ESP8266WiFi.h>
const char* ssid = "MyHotspot";
const char* password = "MyPassword";
const uint16_t serverPort = 80;
WiFiServer server(serverPort);
void setup() {
Serial.begin(115200);
// Create an access point
WiFi.softAP(ssid, password);
IPAddress apIP = WiFi.softAPIP();
Serial.print("Access point IP address: ");
Serial.println(apIP);
// Start the server
server.begin();
Serial.println("Server started");
}
void loop() {
// Check for client connection
WiFiClient client = server.available();
if (client) {
Serial.println("New client connected");
// Wait for client to send data
unsigned long timeout = millis();
while (client.connected() && !client.available()) {
if (millis() - timeout > 5000) {
Serial.println("Timeout waiting for client data");
client.stop();
return;
}
delay(100);
}
// Read client data
String request = client.readStringUntil('\r');
Serial.print("Received message from client: ");
Serial.println(request);
// Send response to client
client.println("Hello from ESP8266");
// Disconnect client
client.stop();
Serial.println("Client disconnected");
}
}
Code for the client
//code for client
#include <ESP8266WiFi.h>
const char* ssid = "MyHotspot";
const char* password = "MyPassword";
const IPAddress serverIP(192, 168, 4, 1);
const uint16_t serverPort = 80;
void setup() {
Serial.begin(115200);
// Connect to WiFi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
}
Serial.println("Connected to WiFi");
}
void loop() {
// Connect to server
WiFiClient client;
if (!client.connect(serverIP, serverPort)) {
Serial.println("Failed to connect to server");
return;
}
// Send message to server
client.println("Hello from ESP8266");
// Wait for response from server
unsigned long timeout = millis();
while (client.connected() && !client.available()) {
if (millis() - timeout > 5000) {
Serial.println("Timeout waiting for server response");
client.stop();
return;
}
delay(100);
}
// Read response from server
String response = client.readStringUntil('\r');
Serial.print("Received response from server: ");
Serial.println(response);
// Disconnect from server
client.stop();
delay(5000);
}
In the first code, within the
loop
function, the code utilizes the
server.available()
method to check for incoming client connections. Upon detecting a client connection, the code proceeds to wait for data from the client, employing a timeout mechanism of 5 seconds. If no data is received within this timeout period, the client is automatically disconnected.